﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using LinFu.IoC.Configuration;

namespace CoreEx.DynamicInvoker.Implementation
{
    [Implements(typeof(IMethodConstructor))]
    public class MethodConstructor : IMethodConstructor
    {
        public IEnumerable<MethodInfo> MakeConstructedMethods(MethodInfo[] genericMethods, Type[] parameterTypes)
        {
            var methodList = new List<MethodInfo>();

            var targetMethods =
                genericMethods.Where(
                    m => m.IsGenericMethodDefinition && m.GetParameters().Count() == parameterTypes.Count());

            foreach (var genericMethod in targetMethods)
            {

                var genericArguments = genericMethod.GetGenericArguments();
                var parameters = genericMethod.GetParameters();
                var genericParameterTypes = new List<Type>();
                foreach (var genericArgument in genericArguments)
                {
                    var genericParameter = parameters.Where(p => p.ParameterType == genericArgument).FirstOrDefault();
                    if (genericParameter != null)
                        genericParameterTypes.Add(parameterTypes[genericParameter.Position]);
                    else
                        genericParameterTypes.Add(typeof(object));
                }




                //var parameters = genericMethod.GetParameters();
                //var genericParameterTypes = new List<Type>();
                //for (int i = 0; i < parameters.Length; i++)
                //{
                //    var parameterInfo = parameters[i];
                //    if (parameterInfo.ParameterType.IsGenericParameter)
                //        genericParameterTypes.Add(parameterTypes[i]);
                //}
                methodList.Add(genericMethod.MakeGenericMethod(genericParameterTypes.ToArray()));




                //var test = genericMethod.GetGenericArguments();

                //var parameters = genericMethod.GetParameters();
                //var genericParameterTypes = new List<Type>();
                //for (int i = 0; i < parameters.Length; i++)
                //{
                //    var parameterInfo = parameters[i];
                //    if (parameterInfo.ParameterType.IsGenericParameter)
                //        genericParameterTypes.Add(parameterTypes[i]);
                //}
                //methodList.Add(genericMethod.MakeGenericMethod(genericParameterTypes.ToArray()));


            }
            return methodList;
        }
    }
}
